package com.zx.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zx.base.shiro.MyShiroRealm;
import com.zx.pojo.Right;
import com.zx.pojo.Role;
import com.zx.pojo.User;
import com.zx.service.RightService;
import com.zx.service.RoleService;
import com.zx.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * RoleController
 *
 * @author LILIBO
 * @since 2022-02-26
 */
@Controller
@RequestMapping("/role")
@Slf4j
public class RoleController {

    @Resource
    private RoleService roleService;

    @Resource
    private RightService rightService;

    @Resource
    private UserService userService;

    /**
     * 分页查询
     */
    @RequestMapping("/list")
    public String list(String roleName, @RequestParam(name = "pageIndex", required = false, defaultValue = "1") Long pageIndex, Model model) {
        // 封装分页对象
        Page<Role> page = new Page<>();
        page.setCurrent(pageIndex);

        // 根据参数和分页对象进行分页查询并设置到作用域
        IPage<Role> rolePager = roleService.findRoles(roleName, page);
        model.addAttribute("rolePager", rolePager);

        // 数据回显
        model.addAttribute("roleName", roleName);
        model.addAttribute("pageIndex", pageIndex);

        // 使用Thymeleaf模板引擎，对应到：resource/templates/user/list.html
        return "role/list";
    }

    /**
     * 跳转到Add页面
     */
    @GetMapping("/add")
    public String toAdd(Model model) {
        List<Right> rights = rightService.getAllRight();
        model.addAttribute("rights", rights);
        return "role/add";
    }

    /**
     * 跳转到Upd页面
     */
    @GetMapping("/edit")
    public String toEdit(Long roleId, Model model) {
        // 通过角色ID获取角色数据
        Role role = roleService.getById(roleId);
        // 向当前角色对象设置权限集合
        role.setRights(rightService.findRightByRoleId(roleId));
        model.addAttribute("role", role);

        // 获取所有权限基础数据
        List<Right> rights = rightService.getAllRight();
        model.addAttribute("rights", rights);
        return "role/edit";
    }

    /**
     * 保存角色信息
     */
    @PostMapping("/save")
    public String save(Role role, String[] rightCodes) {
        // 如果角色的启用状态为null则设置为0
        if (role != null && role.getRoleFlag() == null) {
            role.setRoleFlag(0);
        }
        // 使用Service层方法实现添加角色及对应的权限关系数据
        boolean save = roleService.saveRoleAndRight(role, rightCodes);
        if (save) {
            // 清空权限缓存
            RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
            MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
            realm.clearAllCachedAuthorizationInfo();
            return "redirect:/role/list";
        }
        return "role/add";
    }

    /**
     * 删除角色信息
     */
    @GetMapping("/del/{roleId}")
    @ResponseBody
    public String del(@PathVariable("roleId") Long roleId) {
        Map<String, String> result = new HashMap<>(); // 返回结果
        // 首先，根据角色ID查询用户集合，如果有用户正在使用该角色，则不允许删除（在前端提示）
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("usr_role_id", roleId);
        User one = userService.getOne(qw);
        if (one != null) {
            result.put("result", "inuse");
            return JSON.toJSONString(result);
        }
        // 删除角色：首先删除角色权限对应关系，再删除角色信息
        boolean remove = roleService.removeRoleAndRight(roleId);
        result.put("result", String.valueOf(remove));

        // 清空权限缓存
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAllCachedAuthorizationInfo();
        return JSON.toJSONString(result); // {"result":"inuse|true|false"}
    }
}
